package fiuba.algo3.modelo.vehiculo;

import fiuba.algo3.modelo.factorVial.Obstaculo;
import fiuba.algo3.modelo.factorVial.Sorpresa;
import fiuba.algo3.modelo.Direccion;
import fiuba.algo3.modelo.Posicion;
import fiuba.algo3.modelo.mapa.Cruce;
import fiuba.algo3.modelo.mapa.Calle;
import fiuba.algo3.modelo.mapa.Mapa;

public class Vehiculo{ 
	private Cruce cruceActual;
	private TipoDeVehiculo tipo;
	private int movimientos;
	
	public Vehiculo(TipoDeVehiculo tipo, Posicion posicion, Mapa mapa){
		this.tipo = tipo;
		this.cruceActual = mapa.getCruceEn(posicion);
		this.movimientos = 0;
	}
	
	//solo en tests
	public Vehiculo(TipoDeVehiculo tipo, Cruce cruce){
		this.tipo = tipo;
		this.movimientos = 0;
		this.cruceActual = cruce;
	}
	
	//solo dentro de la clase y en tests (por eso no se cambia a privado)
	public boolean puedoIrA(Direccion direccion){
		boolean sePuede = cruceActual.puedoIrHacia(direccion);
		Obstaculo obstaculo = this.obstaculoA(direccion);
		if(obstaculo != null){
			sePuede = (sePuede && obstaculo.puedePasarUn(this));
		}
		return sePuede;
	}
	
	
	public void moverA(Direccion direccion){
	
		Obstaculo obstaculo = this.obstaculoA(direccion);
		Sorpresa sorpresa = this.sorpresaA(direccion);

		if (obstaculo != null){
			obstaculo.afectarA(this);
		}

		if(puedoIrA(direccion)){
			
			Calle calle = cruceActual.getCalleHacia(direccion);
			
			if (sorpresa != null){
				sorpresa.afectarA(this);
				calle.eliminarSorpresa();
			}
			
			cruceActual = cruceActual.getCalleHacia(direccion).getCruceDestino(this.cruceActual);
			this.incrementarMovimientos(1);				
		}
	}
	
	
	public void incrementarMovimientos(int numeroDeMovimientos) {
		this.movimientos = (movimientos + numeroDeMovimientos);
	}
	
	public void restarMovimientos(int numeroDeMovimientos) {
		this.movimientos = (movimientos - numeroDeMovimientos);
	}

	public TipoDeVehiculo getTipo(){
		return this.tipo;
	}
	
	public int getMovimientos() {
		return this.movimientos;
	}

	public void setTipo(TipoDeVehiculo tipoNuevo) {
		this.tipo = tipoNuevo;
	}
	
	public Cruce getCruceActual(){
		return this.cruceActual;
	}
	
	public Posicion getPosicionActual(){
		return cruceActual.getPosicion();
	}

	private Obstaculo obstaculoA(Direccion direccion){
		Calle unaCalle = cruceActual.getCalleHacia(direccion);
		if(unaCalle != null){
			return ((this.cruceActual.getCalleHacia(direccion)).getObstaculo());
		}else{
			return null;
		}
	}

	private Sorpresa sorpresaA(Direccion direccion){
		Calle unaCalle = cruceActual.getCalleHacia(direccion);
		if(unaCalle != null){
			return ((this.cruceActual.getCalleHacia(direccion)).getSorpresa());
		}else{
			return null;
		}
	}

}